﻿// Copyright (C) 2012 Jeff Tanner <jeff00seattle@gmail.com>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
using System.Web.Security;

using IZ.WebFileManager;
using DotNetSources;
using WebSlideProjector.Configuration;
using WebSlideProjector.Extensions;

namespace WebSlideProjector
{
    public partial class SlideCarousel : DotNetSources.Web.UI.Buttons.BoxContextPage
    {
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>   Event handler. Called by Page for load events. </summary>
        ///
        /// <param name="sender">   Source of the event. </param>
        /// <param name="e">        Event information. </param>
        ////////////////////////////////////////////////////////////////////////////////////////////////////

        protected void Page_Load(object sender, EventArgs e)
        {
            if (AppSettings.SlideCarouselLoginMode)
            {
                if (null == Session["User"])
                {
                    Response.Redirect("~/Login.aspx?ReturnUrl=SlideCarousel.aspx");
                }

                UserBLL userBLL = (UserBLL)Session["User"];

                if (!userBLL.Authorized)
                {
                    Response.Redirect("~/Login.aspx?ReturnUrl=SlideCarousel.aspx");
                }
            }

            if (!Page.IsPostBack)
            {
                this.TitleSpan.InnerText = String.Format("{0} - {1}: Slide Carousel", AppSettings.AssemblyName, AppSettings.AssemblyVersion);
                this.Title = String.Format("{0} - {1}: Slide Carousel", AppSettings.AssemblyName, AppSettings.AssemblyVersion);

                this.SlideFileExt.InnerText = AppSettings.SlideShowFileExtensions;
                this.SlideFileMaxSize.InnerText = AppSettings.SlideShowMaxImageSizeKB;

                this.slideShowWebFileManager();
            }
        }

        #region Web Form Designer generated code

        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>   Raises the initialise event. </summary>
        ///
        /// <remarks>   Jeff Tanner, 2/20/2012. </remarks>
        ///
        /// <param name="e">    Event information to send to registered event handlers. </param>
        ////////////////////////////////////////////////////////////////////////////////////////////////////

        override protected void OnInit(EventArgs e)
        {
            //
            // CODEGEN: This call is required by the ASP.NET Web Form Designer.
            //
            InitializeComponent();
            base.OnInit(e);
        }

        private void InitializeComponent()
        {
            this.Error += new System.EventHandler(this.Page_Error);
        }

        #endregion

        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>   Event handler. Called by ProjectorSetup for error events. </summary>
        ///
        /// <param name="sender">   Source of the event. </param>
        /// <param name="e">        Event information. </param>
        ////////////////////////////////////////////////////////////////////////////////////////////////////

        protected void Page_Error(object sender, EventArgs e)
        {
           Response.Redirect("~/ErrorPages/Error.aspx", true);
        }

        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>   Slide show web file manager. </summary>
        ////////////////////////////////////////////////////////////////////////////////////////////////////

        private void slideShowWebFileManager()
        {
            RootDirectory rootSlides = new RootDirectory
            {
                DirectoryPath = AppSettings.SlideShowFolder,
                ShowRootIndex = false,
                Text = "Slides"
            };

            this.WebFileManager1.RootDirectories.Add(rootSlides);
        }

        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>   Event handler. Called by WebFileManager1 for file uploading events. </summary>
        ///
        /// <param name="sender">   Source of the event. </param>
        /// <param name="e">        Upload file cancel event information. </param>
        ////////////////////////////////////////////////////////////////////////////////////////////////////

        protected void WebFileManager1_FileUploading(object sender, UploadFileCancelEventArgs e)
        {
            string fileName = e.PostedFile.FileName;

            if (!Uri.IsWellFormedUriString(e.SaveName, System.UriKind.Relative))
            {
                e.Cancel = true;
                e.ClientMessage = "New image's name is not URI friendly";
                this.MessageBox.Show(e.ClientMessage, DotNetSources.Web.UI.Buttons.Popup.Icon.Error);

                return;
            }

            /// <summary> validate file extent uploading </summary>
            string fileExtUploading = Path.GetExtension(fileName);
            HashSet<string> validFileExt = AppSettings.SlideShowFileExtensionSet;
            if (!validFileExt.Contains(fileExtUploading))
            {
                e.Cancel = true;
                e.ClientMessage = String.Format("Allowed file extensions for slides: {0}.",
                    string.Join(", ", Array.ConvertAll(validFileExt.ToArray(), i => i.ToString())));
                this.MessageBox.Show(e.ClientMessage, DotNetSources.Web.UI.Buttons.Popup.Icon.Error);

                return;
            }

            /// <summary> validate file type uploading </summary>
            string fileTypeUploading = e.PostedFile.ContentType;
            HashSet<string> validFileTypes = AppSettings.SlideShowFileTypes;
            if (!validFileTypes.Contains(fileTypeUploading))
            {
                e.Cancel = true;
                e.ClientMessage = String.Format("Allowed file types for slides: {0}.",
                    string.Join(", ", Array.ConvertAll(validFileTypes.ToArray(), i => i.ToString())));
                this.MessageBox.Show(e.ClientMessage, DotNetSources.Web.UI.Buttons.Popup.Icon.Error);

                return;
            }

            /// <summary> validate image size uploading </summary>
            int bytesImageSizeUploading = e.PostedFile.ContentLength;
            int kilobytesSlideShowMaxImageSize = Convert.ToInt32(Session["SlideShowMaxImageSizeKB"]);
            if (bytesImageSizeUploading > (kilobytesSlideShowMaxImageSize * 1000))
            {
                e.Cancel = true;
                e.ClientMessage = String.Format("Maximum image size: {0} KiloBytes (KB).", kilobytesSlideShowMaxImageSize);
                this.MessageBox.Show(e.ClientMessage, DotNetSources.Web.UI.Buttons.Popup.Icon.Error);

                return;
            }

            e.ClientMessage = String.Format("Loading: {0}", fileName);
        }

        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>   Event handler. Called by WebFileManager1 for file uploaded events. </summary>
        ///
        /// <param name="sender">   Source of the event. </param>
        /// <param name="e">        Upload file event information. </param>
        ////////////////////////////////////////////////////////////////////////////////////////////////////

        protected void WebFileManager1_FileUploaded(object sender, UploadFileEventArgs e)
        {
            this.MessageBox.Show("Image was successfully uploaded.", DotNetSources.Web.UI.Buttons.Popup.Icon.Info);
        }

        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Event handler. Called by WebFileManager1 for new folder creating events.
        /// </summary>
        ///
        /// <remarks>   Jeff, 2/20/2012. </remarks>
        ///
        /// <param name="sender">   Source of the event. </param>
        /// <param name="e">        Event information. </param>
        ////////////////////////////////////////////////////////////////////////////////////////////////////

        protected void WebFileManager1_NewFolderCreating(object sender, NewFolderCancelEventArgs e)
        {
            string folderPath = e.DestinationDirectory.VirtualPath;

            if (!Uri.IsWellFormedUriString(folderPath, System.UriKind.Relative))
            {
                e.Cancel = true;
                e.ClientMessage = "New folder's name is not URI friendly";
                this.MessageBox.Show(e.ClientMessage, DotNetSources.Web.UI.Buttons.Popup.Icon.Error);
            }
        }

        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>   Event handler. Called by WebFileManager1 for item renaming events. </summary>
        ///
        /// <remarks>   Jeff, 2/20/2012. </remarks>
        ///
        /// <param name="sender">   Source of the event. </param>
        /// <param name="e">        Event information. </param>
        ////////////////////////////////////////////////////////////////////////////////////////////////////

        protected void WebFileManager1_ItemRenaming(object sender, RenameCancelEventArgs e)
        {
            FileAttributes attr = File.GetAttributes(e.FileManagerItem.PhysicalPath);
            bool isDirectory = (attr & FileAttributes.Directory) == FileAttributes.Directory;

            string itemName = e.NewName;
            if (!Uri.IsWellFormedUriString(itemName, System.UriKind.Relative))
            {
                e.Cancel = true;
                e.ClientMessage = String.Format("New {0} name is not URI friendly", isDirectory ? "directory" : "file");
                this.MessageBox.Show(e.ClientMessage, DotNetSources.Web.UI.Buttons.Popup.Icon.Error);

                return;
            }

            if (isDirectory)
            {
            }
            else
            {
                HashSet<string> extensions = AppSettings.SlideShowFileExtensionSet;
                string extFile = Path.GetExtension(itemName);
                if (!extensions.Contains(extFile))
                {
                    e.Cancel = true;
                    e.ClientMessage = "New file name is not an image.";
                    this.MessageBox.Show(e.ClientMessage, DotNetSources.Web.UI.Buttons.Popup.Icon.Error);

                    return;
                }
            }
        }

        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>   Event handler. Called by SlideButton for click events. </summary>
        ///
        /// <param name="sender">   Source of the event. </param>
        /// <param name="e">        SlideShowImage click event information. </param>
        ////////////////////////////////////////////////////////////////////////////////////////////////////

        protected void SlideShowButton_Click(object sender, ImageClickEventArgs e)
        {
            try
            {
                Response.Redirect("~/Default.aspx", true);
            }
            catch (System.Threading.ThreadAbortException)
            {
                // Ignore
            }
            catch (Exception ex)
            {
                HttpContext ctx = HttpContext.Current;
                string origin = ctx.Request.Url.ToString();
                string exMessageHTML = ex.ToErrorMessageHTML(origin, System.Reflection.MethodBase.GetCurrentMethod().Name);

                Session["SiteError"] = exMessageHTML;

                Response.Redirect("~/ErrorPages/Error.aspx", true);
            }
        }

        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>   Raises the error event. </summary>
        ///
        /// <param name="e">    Event information to send to registered event handlers. </param>
        ////////////////////////////////////////////////////////////////////////////////////////////////////

        protected override void OnError(EventArgs e)
        {
            Response.Redirect("~/ErrorPages/Error.aspx", true);

            base.OnError(e);
        }
    }
}